#!/usr/bin/env python3
"""
CodeBuddy - 多智能体协同编程助手
主程序入口

支持命令行模式和交互式模式
"""

import typer
import json
from pathlib import Path
from typing import Optional, List
from rich.console import Console
from rich.panel import Panel
from rich.prompt import Prompt, Confirm
from rich.table import Table
from rich.markdown import Markdown

from config import settings, validate_config
from graph_builder import create_workflow, quick_execute
from utils import logger, console, FileManager

app = typer.Typer(
    name="codebuddy",
    help="🤖 CodeBuddy - 多智能体协同编程助手"
)

@app.command()
def run(
    requirement: Optional[str] = typer.Argument(None, help="用户需求描述"),
    input_file: Optional[Path] = typer.Option(None, "--input", "-i", help="从文件读取需求"),
    output_dir: Optional[Path] = typer.Option(None, "--output", "-o", help="输出目录（如不指定将自动创建）"),
    steps: Optional[List[str]] = typer.Option(None, "--steps", "-s", help="指定执行步骤"),
    interactive: bool = typer.Option(False, "--interactive", "-I", help="交互式模式"),
    config_file: Optional[Path] = typer.Option(None, "--config", "-c", help="配置文件路径")
):
    """执行CodeBuddy工作流"""
    
    try:
        # 验证配置
        validate_config()
    except ValueError as e:
        console.print(f"[red]{e}[/red]")
        console.print("\n请创建 .env 文件并配置 ZHIPU_API_KEY")
        raise typer.Exit(1)
    
    # 显示欢迎信息
    welcome_panel = Panel(
        """
🤖 [bold blue]CodeBuddy - 多智能体协同编程助手[/bold blue]

[green]✨ 功能特性：[/green]
• 🎯 智能需求分析
• 🏗️ 系统架构设计  
• 💻 自动代码生成
• 🧪 单元测试生成
• 🔍 代码质量审查
• 🔒 安全漏洞检测
• ⚡ 性能优化建议
• 📚 文档自动生成

[yellow]开始您的AI编程之旅！[/yellow]
        """,
        title="欢迎使用 CodeBuddy",
        border_style="blue"
    )
    console.print(welcome_panel)
    
    # 获取用户需求
    if interactive:
        user_requirement = interactive_mode()
    elif requirement:
        user_requirement = requirement
    elif input_file and input_file.exists():
        user_requirement = input_file.read_text(encoding='utf-8')
        console.print(f"📁 从文件读取需求: {input_file}")
    else:
        user_requirement = Prompt.ask("请输入您的需求描述")
    
    if not user_requirement:
        console.print("[red]❌ 未提供需求描述[/red]")
        raise typer.Exit(1)
    
    # 生成默认输出目录（如果未指定）
    if not output_dir:
        output_dir = generate_default_output_dir(user_requirement)
        console.print(f"📁 自动创建输出目录: [cyan]{output_dir}[/cyan]")
    
    # 显示需求确认
    req_panel = Panel(
        Markdown(user_requirement),
        title="📋 需求确认",
        border_style="green"
    )
    console.print(req_panel)
    
    if not Confirm.ask("确认开始处理吗？"):
        console.print("操作已取消")
        raise typer.Exit(0)
    
    # 执行工作流
    console.print("\n🚀 启动多智能体协作处理...")
    
    try:
        workflow = create_workflow()
        
        if steps:
            # 执行指定步骤
            result = workflow.execute_partial(user_requirement, steps)
        else:
            # 执行完整工作流
            result = workflow.execute(user_requirement)
        
        # 处理结果 - 总是保存结果
        if result['success']:
            console.print("\n🎉 [bold green]处理完成！[/bold green]")
            
            # 显示摘要
            if 'summary' in result:
                display_summary(result['summary'])
            
            # 自动保存结果到指定目录
            save_results(result, output_dir, user_requirement)
            
            # 显示输出目录信息
            console.print(f"\n📂 [bold green]结果已保存到:[/bold green] [cyan]{output_dir.absolute()}[/cyan]")
            
            # 询问是否查看详细结果
            if Confirm.ask("是否查看详细结果？"):
                display_detailed_results(result)
        
        else:
            console.print(f"\n❌ [bold red]处理失败[/bold red]: {result.get('error', '未知错误')}")
            if result.get('errors'):
                console.print("\n错误详情:")
                for error in result['errors']:
                    console.print(f"  • {error['step']}: {error['error']}")
            
            # 即使失败也保存部分结果
            save_results(result, output_dir, user_requirement)
            console.print(f"\n📂 部分结果已保存到: [cyan]{output_dir.absolute()}[/cyan]")
    
    except KeyboardInterrupt:
        console.print("\n⚠️ 用户中断操作")
        raise typer.Exit(1)
    except Exception as e:
        console.print(f"\n❌ [bold red]执行失败[/bold red]: {e}")
        logger.error(f"执行失败: {e}")
        raise typer.Exit(1)

@app.command()
def demo():
    """运行演示示例"""
    console.print("🎬 [bold blue]CodeBuddy 演示[/bold blue]\n")
    
    demo_requirements = [
        "创建一个命令行计算器，支持四则运算和历史记录功能",
        "开发一个简单的任务管理器，可以添加、删除、标记完成任务",
        "实现一个文件整理工具，按文件类型自动分类整理",
        "构建一个简单的Web API，提供用户注册和登录功能"
    ]
    
    # 显示示例选择
    console.print("请选择一个演示示例：\n")
    for i, req in enumerate(demo_requirements, 1):
        console.print(f"  {i}. {req}")
    
    choice = Prompt.ask(
        "\n请输入选择 (1-4)",
        choices=["1", "2", "3", "4"],
        default="1"
    )
    
    selected_req = demo_requirements[int(choice) - 1]
    console.print(f"\n✅ 已选择: {selected_req}")
    
    # 生成默认输出目录
    output_dir = generate_default_output_dir(selected_req)
    console.print(f"📁 自动创建输出目录: [cyan]{output_dir}[/cyan]")
    
    # 执行演示
    try:
        result = quick_execute(selected_req)
        
        if result['success']:
            console.print("\n🎉 [bold green]演示完成！[/bold green]")
            display_summary(result['summary'])
            
            # 保存演示结果
            save_results(result, output_dir, selected_req)
            console.print(f"\n📂 [bold green]演示结果已保存到:[/bold green] [cyan]{output_dir.absolute()}[/cyan]")
        else:
            console.print(f"\n❌ [bold red]演示失败[/bold red]: {result.get('error')}")
            # 即使失败也保存部分结果
            save_results(result, output_dir, selected_req)
            console.print(f"\n📂 部分结果已保存到: [cyan]{output_dir.absolute()}[/cyan]")
    
    except Exception as e:
        console.print(f"\n❌ 演示执行失败: {e}")

@app.command()
def web():
    """启动Web界面"""
    try:
        import streamlit as st
        import subprocess
        
        console.print("🌐 启动 Streamlit Web 界面...")
        
        # 启动Streamlit应用
        subprocess.run([
            "streamlit", "run", "web_interface.py",
            "--server.port", str(settings.streamlit_port),
            "--server.headless", "true"
        ])
    
    except ImportError:
        console.print("[red]❌ 未安装 streamlit，请运行: pip install streamlit[/red]")
        raise typer.Exit(1)
    except Exception as e:
        console.print(f"[red]❌ 启动Web界面失败: {e}[/red]")
        raise typer.Exit(1)

@app.command() 
def stats():
    """显示代理统计信息"""
    console.print("📊 [bold blue]代理统计信息[/bold blue]\n")
    
    try:
        workflow = create_workflow()
        stats = workflow.get_agent_stats()
        
        # 创建统计表格
        table = Table(title="🤖 AI代理统计")
        table.add_column("代理名称", style="cyan")
        table.add_column("角色", style="green")
        table.add_column("模型", style="yellow")
        table.add_column("调用次数", style="blue")
        table.add_column("成功率", style="red")
        
        for agent_name, stat in stats.items():
            table.add_row(
                stat['name'],
                stat['role'], 
                stat['model'],
                str(stat['performance']['total_calls']),
                stat['performance']['success_rate']
            )
        
        console.print(table)
    
    except Exception as e:
        console.print(f"[red]❌ 获取统计信息失败: {e}[/red]")

def interactive_mode() -> str:
    """交互式模式"""
    console.print("\n🎯 [bold blue]交互式需求收集[/bold blue]")
    
    # 项目类型选择
    project_types = {
        "1": "Web应用",
        "2": "命令行工具", 
        "3": "数据处理脚本",
        "4": "API服务",
        "5": "桌面应用",
        "6": "其他"
    }
    
    console.print("\n📂 项目类型:")
    for key, value in project_types.items():
        console.print(f"  {key}. {value}")
    
    project_type = Prompt.ask(
        "请选择项目类型",
        choices=list(project_types.keys()),
        default="1"
    )
    
    # 功能描述
    description = Prompt.ask("📝 请详细描述您的需求")
    
    # 技术偏好
    tech_preferences = Prompt.ask(
        "⚙️ 技术偏好 (可选，如：Python Flask, React, 等)",
        default=""
    )
    
    # 性能要求
    performance_req = Prompt.ask(
        "⚡ 性能要求 (可选，如：高并发、实时性等)",
        default=""
    )
    
    # 组合需求
    requirement_parts = [
        f"项目类型：{project_types[project_type]}",
        f"功能描述：{description}"
    ]
    
    if tech_preferences:
        requirement_parts.append(f"技术偏好：{tech_preferences}")
    
    if performance_req:
        requirement_parts.append(f"性能要求：{performance_req}")
    
    return "\n".join(requirement_parts)

def display_summary(summary: dict):
    """显示执行摘要"""
    summary_table = Table(title="📊 执行摘要")
    summary_table.add_column("指标", style="cyan")
    summary_table.add_column("值", style="green")
    
    summary_table.add_row("总步骤", str(summary['total_steps']))
    summary_table.add_row("成功步骤", str(summary['successful_steps']))
    summary_table.add_row("失败步骤", str(summary['failed_steps']))
    summary_table.add_row("执行时间", f"{summary['execution_time']}秒")
    summary_table.add_row("成功率", f"{summary['success_rate']:.1f}%")
    
    console.print(summary_table)

def display_detailed_results(result: dict):
    """显示详细结果"""
    console.print("\n📋 [bold blue]详细结果[/bold blue]")
    
    for step_name, step_result in result['results'].items():
        if step_result.get('success', True):
            console.print(f"\n✅ [bold green]{step_name}[/bold green]")
            
            # 显示摘要
            if 'summary' in step_result:
                console.print(f"   📝 {step_result['summary']}")
            
            # 询问是否查看详细内容
            if Confirm.ask(f"查看 {step_name} 的详细结果？"):
                for key, value in step_result.items():
                    if key not in ['success', 'summary'] and isinstance(value, str):
                        console.print(Panel(
                            value[:1000] + "..." if len(value) > 1000 else value,
                            title=f"{step_name} - {key}",
                            border_style="blue"
                        ))

def save_results(result: dict, output_dir: Path, requirement: str):
    """保存结果到文件"""
    output_dir.mkdir(parents=True, exist_ok=True)
    
    console.print(f"\n💾 保存结果到: {output_dir}")
    
    try:
        # 保存需求
        FileManager.safe_write_file(
            str(output_dir / "requirement.txt"),
            requirement
        )
        
        # 保存完整结果
        with open(output_dir / "complete_results.json", 'w', encoding='utf-8') as f:
            json.dump(result, f, ensure_ascii=False, indent=2, default=str)
        
        # 保存各阶段结果
        for step_name, step_result in result['results'].items():
            if step_result.get('success', True):
                step_dir = output_dir / step_name
                step_dir.mkdir(exist_ok=True)
                
                # 保存代码文件
                if 'code_files' in step_result:
                    for file_path, code_content in step_result['code_files'].items():
                        FileManager.safe_write_file(
                            str(step_dir / file_path),
                            code_content,
                            backup=False
                        )
                
                # 保存其他内容
                for key, value in step_result.items():
                    if isinstance(value, str) and key not in ['success', 'summary']:
                        FileManager.safe_write_file(
                            str(step_dir / f"{key}.md"),
                            value,
                            backup=False
                        )
        
        console.print("✅ 结果保存完成")
    
    except Exception as e:
        console.print(f"[red]❌ 保存失败: {e}[/red]")

def generate_default_output_dir(user_requirement: str) -> Path:
    """根据用户需求和时间戳生成默认输出目录"""
    from datetime import datetime
    import re
    
    # 获取当前时间戳
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    
    # 从需求中提取关键词作为项目名称
    # 移除标点符号和特殊字符，保留中英文和数字
    cleaned_requirement = re.sub(r'[^\w\s\u4e00-\u9fff]', '', user_requirement)
    
    # 提取前几个词作为项目名称
    words = cleaned_requirement.split()[:3]  # 取前3个词
    if words:
        project_name = '_'.join(words)[:30]  # 限制长度
    else:
        project_name = "codebuddy_project"
    
    # 创建输出目录名称
    dir_name = f"{project_name}_{timestamp}"
    
    # 创建完整路径（在当前目录下的outputs文件夹中）
    base_output_dir = Path("outputs")
    output_dir = base_output_dir / dir_name
    
    return output_dir

if __name__ == "__main__":
    app() 